<?php
namespace app\common\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Config;

class Key extends Command
{
	protected $dir;
	protected $file;
	protected $power;
	/**
	 * configure 控制台指令入口
	 * 在这里做各种指令设置
	 */
	protected function configure()
	{
		$this->setName('key')//设置名称
			->addArgument('key', Argument::OPTIONAL, "需要更改的秘钥名称")
			->setDescription('key 生成指令,包含【passkey,tokenkey,oauth2key】指令');//设置名称后的显示
	}

	/**
	 * execute 控制台指令出口
	 * 在这里对业务进行处理
	 * @param  Input  $input  用户需要输入的信息
	 * @param  Output $output 用户需要输入的信息
	 * @return str         返回到控制台显示
	 */
	protected function execute(Input $input, Output $output)
	{
		$input = self::argumentDispose($input,$output);
		$output->writeln('新的'.$input['param'].' 钥匙: [ '.$input['data']['md5'].' ]修改成功');
	}

	/**
	 * argumentDispose 传入的参数处理
	 * @param  object $input  用户需要输入的信息
	 * @param  object $output 用户需要输入的信息
	 * @return string         结果或者直接输入控制台
	 */
	protected static function argumentDispose($input,$output)
	{
		// 获取参数
		$param = $input->getArgument('key');
		// 文件以及文件夹检测,不存在则创建
		$path = self::createFile();
		switch ($param)
		{
			case 'passkey':
				// 内部处理 写入配置 和生成秘钥
				$data = self::keyDispose($param,$path);
				// 外部处理 对指定的key进行变更
				$res = self::keyWrite($param,$data,$output);
			break;
			case 'oauthkey':
				// 内部处理 写入配置 和生成秘钥
				$data = self::keyDispose($param,$path);
				// 外部处理 对指定的key进行变更
				$res = self::keyWrite($param,$data,$output);
			break;
			case 'tokenkey':
				// 内部处理 写入配置 和生成秘钥
				$data = self::keyDispose($param,$path);
				// 外部处理 对指定的key进行变更
				$res = self::keyWrite($param,$data,$output);
			break;
			default:
				$error = 'key指令之后必须有【passkey】【tokenkey】【oauthkey】其中之一的指令内容';
				$output->writeln($error);exit;
			break;
		}
		return $res;
	}

	/**
	 * keyDispose 生成一个Key 并且处理该key
	 * @param  string $param 要处理的内容
	 * @param  string $path  要处理的目标文件
	 * @return array 返回必要的Key信息
	 */
	protected static function keyDispose($param,$path)
	{
		$data['time'] = time();
		$data['rand'] = mt_rand(10000,99999);
		$data['date'] = date('Y-m-d h:i:s',$data['time']);
		$md5 = $data['time'].$data['rand'];
		$data['md5'] = md5($md5);
		$str = '
		'.$param.' = [
			DataTime=>'.$data['date'].',
			ProofOne=>'.$data['time'].',
			ProofTwo=>'.$data['rand'].',
			Key=>'.$data['md5'].',
		],';
		// 记录点路径
		$key_url = $path['dir'].'\\'.$path['file'];
		file_put_contents($key_url,$str);
		return $data;
	}

	/**
	 * keyWrite key写入到指定的地方
	 * @param  [type] $data [description]
	 * @return [type]       [description]
	 */
	protected static function keyWrite($param,$data,$output)
	{
		// 获取配置信息
		$config = Config::get('web.self.'.$param.'');
		$configArr = explode('-',$config['keyname']);
		// 读取修改目标
		$text = file_get_contents($config['paht']);
		switch (count($configArr))
		{
			case '1':
				$editpp = "/'{$configArr[0]}'.*[,]/";
				$editstr = "'{$configArr[0]}'=>'{$data['md5']}',";
			break;
			case '2':
				$editpp = "/'{$configArr[1]}'.*[,]/";
				$editstr = "'{$configArr[1]}'=>'{$data['md5']}',";
			break;
			case '3':
				$editpp = "/'{$configArr[2]}'.*[,]/";
				$editstr = "'{$configArr[2]}'=>'{$data['md5']}',";
			break;
			default:
				$error = '配置级别查找深度,最大不能超过3级,每级之间以 - 规范';
				$output->writeln($error);exit;
			break;
		}
		$edit_text = preg_replace($editpp,$editstr,$text,1);
		$res =file_put_contents($config['paht'],$edit_text);
		return ['param'=>$param,'data'=>$data];
	}

	/**
	 * createFile 创建安全目录已经文件
	 */
	protected static function createFile()
	{
		// 获取配置信息
		$config = Config::get('web.self');
		if (empty($config))
		{	
			// 目录路径
			$dir = iconv("UTF-8", "GBK", 'application\\common\\command\\self');
			// 文件名称
			$file = 'key.log';
			// 权限
			$power = '0777';
		}
		else
		{
			// 目录路径
			$dir = iconv("UTF-8", "GBK", $config['paht']);
			// 文件名称
			$file = $config['file'];
			// 权限
			$power = $config['power'];
		}
		// 如果文件夹不存在,则创建文件夹
		if (!file_exists($dir)) mkdir ($dir,$power,true);
		// 如果文件不存在则创建文件
		if(!is_file($dir.'\\'.$file)) touch($dir.'\\'.$file);
		// 对文件权限进行变更
		chmod($dir.'\\'.$file,$power);
		return ['dir'=>$dir,'file'=>$file];
	}
}